package v1

import (
	"fmt"
	"hr/api/dto"
	"hr/api/middleware"
	"hr/db"
	"hr/service"
	"hr/utils"
	"regexp"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/gin-gonic/gin"
)

// Login
// @Summary 登录
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param LoginRequest body dto.LoginRequest true "登录信息"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/account/login [post]
func Login(c *gin.Context) {
	params := dto.LoginRequest{}
	if err := c.ShouldBindJSON(&params); err != nil {
		utils.EchoError(c, "用户名或密码不能为空")
		return
	}
	_, _, tag := db.GetUsers(map[string]interface{}{
		"username": params.Username,
	})
	if tag == "0" || tag == "1" {
		utils.EchoError(c, "用户不存在")
		return
	}

	u, _, tag := db.GetUsers(map[string]interface{}{
		"username": params.Username,
		"password": utils.Md5V(params.Password),
	})
	if tag == "0" {
		utils.EchoError(c, "密码错误")
		return
	}

	if u.Status == "1" {
		utils.EchoError(c, "您已限制登录，请联系管理员")
		return
	}

	uPlus := db.UserAndMenu{}
	uPlus.User = u
	r, _ := db.GetRoleList(u.RoleID)
	uPlus.Role = r

	userId := fmt.Sprintf("user_%d", u.ID)
	expireTime := time.Hour * 24

	calsm := middleware.JwtModel{
		StandardClaims: jwt.StandardClaims{
			Issuer:    "hsyedu.com",
			Id:        userId,
			ExpiresAt: time.Now().Add(expireTime).Unix(),
			IssuedAt:  time.Now().Unix(),
			NotBefore: time.Now().Unix(),
		},
	}

	token, err := middleware.CreateJWT(calsm)
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}
	_ = service.FileCache.Save(userId, token, expireTime)
	utils.EchoSuccess(c, map[string]interface{}{
		"user":  u,
		"token": token,
	}, "登录成功")
	return
}

// GetUserInfo
// @Summary 获取用户信息
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param Access-Token header string true "Authentication header"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/auth/info [get]
func GetUserInfo(c *gin.Context) {
	id, err := middleware.GetCurrentUserId(c)
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}
	user, err := db.GetUserInfo(id)
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}
	utils.EchoSuccess(c, user, "请求成功")
	return
}

// Register
// @Summary 注册
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param RegisterRequest body dto.RegisterRequest true "注册信息"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/account/register [post]
func Register(c *gin.Context) {
	params := dto.RegisterRequest{}
	if err := c.ShouldBindJSON(&params); err != nil {
		utils.EchoError(c, "注册信息不能为空")
		return
	}
	cacheCode, _ := service.FileCache.Fetch(params.Username)
	if cacheCode != params.Code {
		utils.EchoError(c, "验证码错误")
		return
	}

	u, _, tag := db.GetUsers(map[string]interface{}{
		"email": params.Email,
	})

	if tag == "2" {
		utils.EchoError(c, "该邮箱已存在")
		return
	}

	u, _, tag = db.GetUsers(map[string]interface{}{
		"username": params.Username,
	})

	if tag == "2" {
		utils.EchoError(c, "该账号已存在")
		return
	}

	params.Password = utils.Md5V(params.Password)
	u, err := db.RegisterUser(params)
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}
	utils.EchoSuccess(c, u, "注册成功")
	_ = service.FileCache.Delete(params.Username)
	return
}

// SendMailCode
// @Summary 发送邮箱验证码
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param MailRequest body dto.MailRequest true "邮箱信息"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/account/mail [post]
func SendMailCode(c *gin.Context) {
	params := dto.MailRequest{}
	if err := c.ShouldBindJSON(&params); err != nil {
		utils.EchoError(c, "邮箱不能为空")
		return
	}
	reEmail := `[\w\.]+@\w+\.[a-z]{2,3}(\.[a-z]{2,3})?`
	re := regexp.MustCompile(reEmail)
	reMail := re.FindAllStringSubmatch(params.Email, -1)
	if len(reMail) <= 0 {
		utils.EchoError(c, "邮箱格式输入有误")
		return
	}
	info, err := utils.SendEmail(c, params.Email, "朋友")
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}
	_ = service.FileCache.Save(params.Email, info, time.Minute*5)
	utils.EchoSuccess(c, nil, "验证码发送成功，请注意查收")
	return
}

// UpdatePassword
// @Summary 修改密码
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param RegisterRequest body dto.RegisterRequest true "注册信息"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/account/updatePassword [post]
func UpdatePassword(c *gin.Context) {
	params := dto.RegisterRequest{}
	if err := c.ShouldBindJSON(&params); err != nil {
		utils.EchoError(c, "账号信息以及验证码不能为空")
		return
	}
	cacheCode, _ := service.FileCache.Fetch(params.Username)
	if cacheCode != params.Code {
		utils.EchoError(c, "验证码错误")
		return
	}

	u, _, tag := db.GetUsers(map[string]interface{}{
		"username": params.Username,
	})

	if tag == "0" || tag == "1" {
		utils.EchoError(c, "该账号不存在")
		return
	}

	u, _, tag = db.GetUsers(map[string]interface{}{
		"username": params.Username,
		"password": utils.Md5V(params.Password),
	})

	if tag == "0" || tag == "1" {
		utils.EchoError(c, "旧密码输入有误")
		return
	}

	user, err := db.UpdatePassword(u.ID, utils.Md5V(params.Password))
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}

	utils.EchoSuccess(c, user, "密码修改成功")
	_ = service.FileCache.Delete(params.Username)
	return
}

// ForgetPassword
// @Summary 忘记密码
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param RegisterRequest body dto.RegisterRequest true "注册信息"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/account/forgetPassword [post]
func ForgetPassword(c *gin.Context) {
	params := dto.RegisterRequest{}
	if err := c.ShouldBindJSON(&params); err != nil {
		utils.EchoError(c, "账号信息以及验证码不能为空")
		return
	}
	cacheCode, _ := service.FileCache.Fetch(params.Username)
	if cacheCode != params.Code {
		utils.EchoError(c, "验证码错误")
		return
	}

	u, _, tag := db.GetUsers(map[string]interface{}{
		"username": params.Username,
	})

	if tag == "0" || tag == "1" {
		utils.EchoError(c, "该账号不存在")
		return
	}

	user, err := db.UpdatePassword(u.ID, utils.Md5V(params.Password))
	if err != nil {
		utils.EchoError(c, err.Error())
		return
	}

	utils.EchoSuccess(c, user, "密码修改成功")
	_ = service.FileCache.Delete(params.Username)
	return
}

// Logout
// @Summary 退出登录
// @Tags 账号相关api
// @Accept  json
// @Produce json
// @Param Access-Token header string true "Authentication header"
// @Success 200 {object} utils.JsonContent
// @Failure 400 {object} utils.JsonContent
// @Failure 500 {object} utils.JsonContent
// @Router /api/v1/auth/logout [post]
func Logout(c *gin.Context) {
	id, _ := middleware.GetCurrentUserId(c)
	_ = service.FileCache.Delete(fmt.Sprintf("user_%d", id))
	utils.EchoSuccess(c, nil, "退出成功")
	return
}
